Skip to content

perf(web-ui): reduce post-interactive workspace and session pressure#1032

Merged
limityan merged 1 commit into
GCWing:mainfrom
limityan:yanzhn/startup-m2-pressure
Jun 3, 2026
Merged

perf(web-ui): reduce post-interactive workspace and session pressure#1032
limityan merged 1 commit into
GCWing:mainfrom
limityan:yanzhn/startup-m2-pressure

Conversation

@limityan
Copy link
Copy Markdown
Collaborator

@limityan limityan commented Jun 2, 2026

Summary

  • Adds finer startup/session tracing for native window phases, API command pressure, and historical-session restore frames.
  • Defers post-interactive local workspace refresh pressure while keeping remote workspace behavior unchanged.
  • Restores local historical sessions with the latest 8 turns first, keeps remote restore at 3 turns, and hydrates full history after latest content paints or a bounded timeout.
  • Splits large completed model rounds for virtual rendering, defers expensive markdown syntax highlighting, and preserves active/streaming/recent tool output behavior.
  • Keeps a history loading overlay until the latest turn has readable text in the viewport, then lets full history hydrate in the background.
  • Strengthens the performance E2E guard to check usable latest text, naked blank gaps, placeholder coverage, and input anchoring.
  • Fixes review-found edge cases: full hydrate preserves turns appended after partial restore, the history overlay blocks click-through activation, searching a partially loaded session releases full hydrate early, saved custom themes restore before first React paint, and tail-restored recommendation context uses the backend turn index.
  • Limits API payload byte estimation to explicit perf trace mode so default startup/session timing is not polluted by observer-side object traversal.
  • Shows global turn numbers for partial historical tail restores while keeping previous/next navigation bounded to already loaded turns.

Updates #949. This PR does not close the issue; native startup outliers remain open follow-up work.

Performance Data

Current PR head after P2 safety amend: 8b90809d, base f46113e6. The release-fast performance data below was collected before the review-safety amend on head b0747d4a against base 8318ab32; the latest amend adds functional safeguards and focused tests, and does not claim a new performance delta. The large-session fixture has 80 turns with markdown, code blocks, tables, tools, and visible latest-turn narrative text.

Key End-To-End Results

User scenario Previous problem sample Current result Delta Reading
First open 80-turn historical session until latest text is readable 965.1 ms p50 305.9 ms, range 305.3-322.1 ms -659.2 ms (-68.3%) Clear latest-content win
First open 80-turn historical session after full history hydrate 1118.1 ms p50 667.8 ms, range 607.2-699.7 ms -450.3 ms (-40.3%) Clear win, background hydrate still visible in data
Warm reopen 80-turn historical session until latest text is readable 457.7 ms range 315.6-325.5 ms, avg 320.6 ms about -137.1 ms (-30.0%) Improvement, smaller than first-open
Cold launch to chat shell interactive Earlier controlled p50 745.2 ms latest run 1077.5 ms Regression/no claim Not solved in this PR

Historical Session Viewport Quality

Viewport check Current result Reading
First-open latest item visible 218.5-238.7 ms Virtual list anchors latest content quickly
First-open latest text readable 305.3-322.1 ms Remaining cost is frontend render/markdown/virtual measurement, not backend I/O
First-open backend restore 3-4 ms backend, 18.7-22.9 ms bridge Restore I/O is not the dominant slice in this fixture
First-open placeholder visible 62.7-70.5 ms User sees a loading state instead of a naked blank while latest text is not ready
Naked blank before latest text 0 samples across the latest 3 first-open runs and 2 warm-reopen runs The prior white area is covered by an explicit loading state
Warm-reopen input anchor input top 952 px, bottom 1028 px in latest runs Guards against the previous centered-input regression

Startup Outlier Analysis

This PR should not be read as a startup win. The latest startup run still shows work before the interactive shell:

Startup slice Latest observed result Current reading
Interactive shell ready 1077.5 ms Still above the earlier controlled p50
First script eval 852.3 ms Follows native webview/window timing
Native webview build 579 ms Major pre-frontend slice
Native show wait 150 ms Intentional wait still visible
Before-interactive command bridge 326.5 ms total bridge time Follow-up should reduce startup invoke pressure
Slow before-interactive commands get_config 108.1 ms, remote_get_workspace_info 97.5 ms Startup work remains a separate bottleneck

Risks And Functional Impact

  • Local historical session first restore now requests up to 8 latest turns instead of 3. This improves latest-context rendering, but can increase first payload for very heavy turns.
  • Remote historical restore intentionally stays at 3 turns to avoid changing remote compatibility or payload behavior in this PR.
  • Complete history still hydrates in the background. Fast scrolling into older history before hydrate completes can still wait on that background load.
  • During tail restore, some auxiliary consumers can temporarily see only the loaded tail in dialogTurns. This PR protects the main chat viewport, search hydration release, appended-turn merge, and recommendation context turn index, but it does not introduce a global explicit partial-session model.
  • Searching while full history is pending now releases full hydrate early. Until hydrate completes, search results still reflect loaded content only; this is a bounded transient state rather than a permanent partial-search boundary.
  • The history overlay blocks pointer activation behind the loading state while preserving the normal wheel/scroll path. Touch-drag interaction during the very short overlay period is intentionally not treated as an actionable message interaction.
  • Model-round chunking is limited to completed, terminal, non-streaming rounds without active/recent tools. Live streaming and active tool output should keep existing behavior. Large historical model rounds may briefly show an inline loading marker while earlier/later groups render progressively.
  • Inactive local workspace rows defer git refresh until activation or menu open. The first menu open for an inactive local workspace can briefly show git-dependent worktree actions in a loading/disabled state. Remote workspace behavior is intentionally unchanged.
  • Saved custom themes are now restored before first React paint when bootstrap cannot resolve them. This preserves theme experience, but custom-theme users can pay one extra themes config read during before-render initialization; built-in and system theme startup paths stay on the bootstrap path.
  • Default API trace keeps timing, bridge, pressure, and command data, but no longer computes request/response byte estimates unless BITFUN_PERF_TRACE_ENABLED is set. This avoids observer overhead in normal runs; payload-size investigations must explicitly enable perf trace mode.
  • Partial historical session headers now display global turn numbers. Previous/next controls intentionally navigate only inside the loaded range until full hydrate completes; unloaded older turns are not exposed as jump targets during the transient partial state.
  • Startup outliers are not fixed here. The issue remains open for native window lifecycle and startup invoke-pressure follow-up.

Verification

  • After rebase to f46113e6:
    • pnpm --dir src/web-ui run test:run src/infrastructure/theme/core/ThemeService.test.ts src/app/startup/startupPerformanceContract.test.ts: 27 passed.
    • pnpm --dir src/web-ui run test:run src/flow_chat/store/FlowChatStore.test.ts src/flow_chat/components/modern/ModernFlowChatContainer.history-state.test.tsx: 44 passed.
    • pnpm --dir src/web-ui run type-check.
    • git diff --check gcwing/main...HEAD.
  • P2 safety amend on 8b90809d:
    • pnpm --dir src/web-ui run test:run src/infrastructure/api/service-api/ApiClient.test.ts src/flow_chat/components/modern/ModernFlowChatContainer.history-state.test.tsx: 21 passed.
    • pnpm run type-check:web.
    • git diff --check.
  • Earlier PR verification before review-safety amend:
    • pnpm run lint:web
    • pnpm --dir src/web-ui run type-check
    • pnpm --dir src/web-ui run test:run src/flow_chat/components/modern/VirtualMessageList.layout.test.ts src/flow_chat/components/modern/modelRoundProgressiveRender.test.ts src/flow_chat/components/modern/ModernFlowChatContainer.history-state.test.tsx src/flow_chat/store/modernFlowChatStore.test.ts src/flow_chat/store/FlowChatStore.test.ts src/shared/utils/startupTrace.test.ts src/infrastructure/theme/core/ThemeService.test.ts src/app/startup/startupPerformanceContract.test.ts
    • pnpm --dir src/web-ui run test:run src/app/components/NavPanel/sections/workspaces/workspaceGitRefreshOptions.test.ts src/infrastructure/api/service-api/ApiClient.test.ts src/infrastructure/api/adapters/tauri-adapter.test.ts src/shared/utils/logger.test.ts
    • pnpm --dir src/web-ui run test:run src/flow_chat/store/FlowChatStore.test.ts src/flow_chat/components/modern/ModernFlowChatContainer.history-state.test.tsx src/component-library/components/Markdown/Markdown.test.tsx
    • pnpm run desktop:build:release-fast
    • pnpm run check:repo-hygiene
    • cargo test -p bitfun-core load_session_tail_turns -- --nocapture
    • cargo test -p bitfun-core restore_session_view -- --nocapture
    • Release-fast E2E after the overlay fix: 3 first-open runs, 2 warm-reopen runs, and 1 startup run.

@limityan limityan force-pushed the yanzhn/startup-m2-pressure branch from 966ef58 to cf0b337 Compare June 2, 2026 05:58
@limityan limityan marked this pull request as draft June 2, 2026 10:00
@limityan limityan force-pushed the yanzhn/startup-m2-pressure branch 5 times, most recently from 4af804e to b0747d4 Compare June 3, 2026 07:47
@limityan limityan marked this pull request as ready for review June 3, 2026 08:00
@limityan limityan force-pushed the yanzhn/startup-m2-pressure branch 3 times, most recently from c09e19b to 6e078cd Compare June 3, 2026 10:26
@limityan limityan force-pushed the yanzhn/startup-m2-pressure branch from 6e078cd to 8b90809 Compare June 3, 2026 10:51
@limityan limityan merged commit 15c0076 into GCWing:main Jun 3, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant